package cn.lyjuan.jenkins.plugin.qcloud;

import cn.lyjuan.base.util.DateUtils;
import cn.lyjuan.base.util.RandomUtils;
import cn.lyjuan.base.util.StringUtils;
import cn.lyjuan.jenkins.plugin.qcloud.util.CosUtil;
import edu.umd.cs.findbugs.annotations.NonNull;
import hudson.EnvVars;
import hudson.Launcher;
import hudson.Extension;
import hudson.FilePath;
import hudson.util.FormValidation;
import hudson.model.AbstractProject;
import hudson.model.Run;
import hudson.model.TaskListener;
import hudson.tasks.Builder;
import hudson.tasks.BuildStepDescriptor;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;

import javax.servlet.ServletException;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.time.LocalDateTime;

import jenkins.tasks.SimpleBuildStep;
import org.jenkinsci.Symbol;
import org.kohsuke.stapler.DataBoundSetter;

public class QCloudCosUpload extends Builder implements SimpleBuildStep {

    private final String secretId;
    private final String secretKey;
    private final String bucket;
    private final String region;
    private final String file;
    private String fileName;
    private String prefixPath;

    @DataBoundConstructor
    public QCloudCosUpload(String secretId, String secretKey, String bucket, String region, String file) {
        this.secretId = secretId;
        this.secretKey = secretKey;
        this.bucket = bucket;
        this.region = region;
        this.file = file;
    }

    @Override
    public void perform(Run<?, ?> run, FilePath workspace, @NonNull EnvVars env, Launcher launcher, TaskListener listener) throws InterruptedException, IOException {
        listener.getLogger().println("secretId: " + this.secretId + ", secretKey: " + this.secretKey + ", bucket: " + this.bucket + ", region: " + this.region);
        File f = new File(this.file);
        if (!f.isFile())
            throw new FileNotFoundException(this.file + " file not found");

        // 处理文件名
        realFileName();

        listener.getLogger().println("cos upload " + f.getAbsolutePath() + " to " + fileName);


        String cosFile = CosUtil.uploadFile(this.secretId, this.secretKey, this.region, this.bucket, f, this.fileName);
        listener.getLogger().println("cos upload " + f.getAbsolutePath() + " to " + cosFile + " Successful");
    }

    public void realFileName() {
        // 如果fileName为空，随机文件名；如果不为空，使用fileName忽略prefixPath
        if (StringUtils.isNull(this.fileName)) {// 随机文件名
            // todo 在随机文件名的时候，需要保证云端文件名不重复
            this.fileName = DateUtils.format(LocalDateTime.now(), "HHmmss") + RandomUtils.uuid();
            int lastIndexSuffix = this.file.lastIndexOf(".");
            if (lastIndexSuffix > -1) {
                this.fileName += this.file.substring(lastIndexSuffix);
            }
            if (!StringUtils.isNull(prefixPath))// 如果前经不为空，则拼接前缀
                this.fileName = this.prefixPath + (this.prefixPath.endsWith("/") ? "" : "/") + this.fileName;
        }
    }

    @Symbol("qcloudCosUpload")
    @Extension
    public static final class DescriptorImpl extends BuildStepDescriptor<Builder> {

        public FormValidation doCheckName(@QueryParameter String secretId, @QueryParameter String secretKey
                , @QueryParameter String bucket, @QueryParameter String region, @QueryParameter String file)
                throws IOException, ServletException {
            if (StringUtils.isNull(secretId))
                return FormValidation.error("secretId is null");
            if (StringUtils.isNull(secretKey))
                return FormValidation.error("secretKey is null");
            if (StringUtils.isNull(bucket))
                return FormValidation.error("cos bucket is null");
            if (StringUtils.isNull(region))
                return FormValidation.error("cos region is null");
            if (StringUtils.isNull(file))
                return FormValidation.error("file is null");
            File tmpFile = new File(file);
            if (!tmpFile.isFile())
                return FormValidation.error("file: " + file + " not exists");
            return FormValidation.ok();
        }

        @Override
        public boolean isApplicable(Class<? extends AbstractProject> aClass) {
            return true;
        }

        @Override
        public String getDisplayName() {
//            return Messages.HelloWorldBuilder_DescriptorImpl_DisplayName();
            return "";
        }

    }


    public String getSecretId() {
        return this.secretId;
    }

    public String getSecretKey() {
        return this.secretKey;
    }

    public String getBucket() {
        return this.bucket;
    }

    public String getRegion() {
        return this.region;
    }

    public String getFile() {
        return this.file;
    }

    public String getFileName() {
        return this.fileName;
    }

    public String getPrefixPath() {
        return this.prefixPath;
    }

    @DataBoundSetter
    public void setPrefixPath(String prefixPath) {
        this.prefixPath = prefixPath;
    }

    @DataBoundSetter
    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
}
